home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic Source Code
/
Visual Basic Source Code.iso
/
vbsource
/
vbdatabs
/
vbdfile.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-03-18
|
54KB
|
1,819 lines
// ------------------------------- //
// -------- Start of File -------- //
// ------------------------------- //
// ----------------------------------------------------------- //
// C++ Source Code File Name: vbdfile.cpp
// Compiler Used: MSVC40, DJGPP 2.7.2.1, GCC 2.7.2.1, HP CPP 10.24
// Produced By: Doug Gaer
// File Creation Date: 02/04/1997
// Date Last Modified: 03/18/1999
// Copyright (c) 1997 Douglas M. Gaer
// ----------------------------------------------------------- //
// ------------- Program Description and Details ------------- //
// ----------------------------------------------------------- //
/*
The VBD C++ classes are copyright (c) 1997, by Douglas M. Gaer.
All those who put this code or its derivatives in a commercial
product MUST mention this copyright in their documentation for
users of the products in which this code or its derivative
classes are used. Otherwise, you have the freedom to redistribute
verbatim copies of this source code, adapt it to your specific
needs, or improve the code and release your improvements to the
public provided that the modified files carry prominent notices
stating that you changed the files and the date of any change.
THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
CORRECTION.
The VBD file manager class is responsible for handling all
low-level file operations through the use of VBDFile objects
or by inheriting the VBDFile class. Low-level file operations
refer to functions such as: Create(), Open(), Read(), Write(),
Alloc(), Delete(), and Close(). These functions contain all the
routines needed to create and maintain VBD files in accordance
with the VBD File Format. VBDFile objects are reference counted
and must be created dynamically due to the way reference
counting is implemented.
*/
// ----------------------------------------------------------- //
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "vbdfile.h"
// Define the __DOS_INCLUDES__ macro to use DOS path separators
#ifdef __DOS_INCLUDES__
#include <sys\types.h>
#include <sys\stat.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#endif
// Init all the static data members
static char ClosedFileName[MaxNameLength] = "closed.vbd";
// Current VBD file manager version number.
// 07/22/1998 changed to version 1025 from version 1024.
// 08/31/1998 changed to version 1027 from version 1025.
// 02/10/1999 changed to version 1029 from version 1027.
// 03/18/1999 changed to from version 1029 to final release version 1031.
__LWORD__ VBDFile::VBDVersion = 1031;
// 08/31/1998 added revision letter 'A' to signature. Revision 'A'
// adds a 32-bit checksum routines, not included in previous versions.
__SBYTE__ VBDFile::VBDSignature[8] = {'V', 'B', 'D', 'F', 'I', 'L', 'E', 'A'};
VBDFile::VBDFile()
// Creates a VBD file object, with refcount of one.
{
strcpy(FileName, ClosedFileName); // Set the initial file name
fp = 0;
Status = 0x01; // good, read-only, and closed
}
VBDFile::~VBDFile()
{
Close();
}
int VBDFile::Create(const char *FName, FAU StaticSize)
// Creates and opens a new file named FName, truncating it
// if it already exists. The area at the front of the file
// of length StaticSize + sizeof(FileHeader) is reserved.
{
// First, close the current file if open.
Close();
Status = 0x05; // Set read/write bit and good bit
// Create, truncate if already exists
fp = ::fopen(FName, "w+b");
if(fp == 0) {
#ifdef CPP_EXCEPTIONS
throw CFileCreationError();
#else
Error->SignalException(EHandler::FileCreationError);
#endif
}
else {
Status |= 2; // Set open bit
strcpy(FileName, FName);
Header.HeapStart = StaticSize + sizeof(FileHeader);
LastOperation = READ; // So Write() works right the first time
InitHdr();
}
// Returns 1 if the file was successfully created and opened.
return IsOpen();
}
void VBDFile::InitHdr()
// Sets up the header area in the file. If there's
// statically allocated data beyond the header, write
// a 0 to the last byte of it, so that there will be no
// unexpected end of file errors. The rest of the static
// area stays uninitialized.
{
Header.FreeSpace = 0;
Header.EndOfFile = Header.HeapStart;
Header.HighestVB = 0; // No blocks allocated in the file
memcpy(Header.Signature, VBDSignature, 8); // Copy signature
Header.Version = VBDVersion;
// Set the revision letter
char revision[8];
memmove(revision, VBDSignature, 8);
rev_letter = revision[7];
// 03/13/1998: Write the VBD file header and flush the disk
// buffers to maintain file integrity during multiple file
// access.
WriteHdr();
if(Header.HeapStart > sizeof(FileHeader)) {
__SBYTE__ zero_byte = 0;
Write(&zero_byte, 1, Header.HeapStart-1);
}
}
int VBDFile::Open(const char *FName, AccessMode Mode)
// Opens the FName file. File must exist and be a VBDFile type
// or error occurs. This function will check the revsion letter
// when opening an existing file.
{
char *mode_str;
// First, close the current file if open.
Close();
if(Mode == READONLY) {
mode_str = "rb";
Status = 0x01; // set good bit, reset read/write bit
}
else {
mode_str = "r+b";
Status = 0x05; // Set good bit and read/write bit
}
fp = ::fopen(FName, mode_str);
if(fp == 0) {
#ifdef CPP_EXCEPTIONS
throw CFileOpenError();
#else
Error->SignalException(EHandler::FileOpenError);
#endif
}
else {
Status |= 2; // Set open bit
strcpy(FileName, FName);
LastOperation = WRITE; // So Read() works right the first time
ReadHdr();
// Test file type, checking the revision letter
if(memcmp(Header.Signature, VBDSignature, 7)) {
#ifdef CPP_EXCEPTIONS
throw CWrongFileType();
#else
Error->SignalException(EHandler::WrongFileType);
#endif
}
// Set the revision letter according to the file header
char revision[8];
memmove(revision, Header.Signature, 8);
rev_letter = revision[7];
}
// 03/11/1998: This code was added to ensure that true end of
// file is stored in the VBD file header.
INT32 filesize;
filesize = FileSize(FName);
if(Header.EndOfFile < filesize) {
Header.EndOfFile = filesize;
Flush();
}
return IsOpen(); // Returns 1 if file opened successfully, else 0.
}
int VBDFile::ReOpen(const char *FName, AccessMode Mode)
// Reopens the FName file. File must exist and be a VBD file type
// or error occurs. This function will check the revsion letter
// when reopening an existing file.
{
char *mode_str;
if(Mode == READONLY) {
mode_str = "rb";
Status = 0x01; // set good bit, reset read/write bit
}
else {
mode_str = "r+b";
Status = 0x05; // Set good bit and read/write bit
}
// Close the file and flush all buffers
::rewind(fp);
if(!ReadOnly()) ::fflush(fp);
::fclose(fp);
// Reopen after closing the file
fp = ::fopen(FName, mode_str);
if(fp == 0) {
#ifdef CPP_EXCEPTIONS
throw CFileOpenError();
#else
Error->SignalException(EHandler::FileOpenError);
#endif
}
else {
Status |= 2; // Set open bit
strcpy(FileName, FName);
LastOperation = WRITE; // So Read() works right the first time
ReadHdr();
// Test file type, checking the revision letter
if(memcmp(Header.Signature, VBDSignature, 7)) {
#ifdef CPP_EXCEPTIONS
throw CWrongFileType();
#else
Error->SignalException(EHandler::WrongFileType);
#endif
}
// Set the revision letter according to the file header
char revision[8];
memmove(revision, Header.Signature, 8);
rev_letter = revision[7];
}
// 03/11/1998: This code was added to ensure that true end of
// file is stored in the VBD file header.
INT32 filesize;
fi